<template>
  <h2>
    寻找最短路径
    <el-button type="info" @click="goUrl('home')" style="float: right">
      返回首页
    </el-button>
  </h2>
  <div class="topology-tree">
    <!-- 绘制拓扑树 -->
    <svg :width="width" :height="height">
      <!-- 绘制边 -->
      <g v-for="(edge, index) in visibleEdges" :key="index">
        <!-- 边 -->
        <line
          :x1="tree.nodes[edge.from].x"
          :y1="tree.nodes[edge.from].y"
          :x2="tree.nodes[edge.to].x"
          :y2="tree.nodes[edge.to].y"
          stroke="#aaa"
          stroke-width="2"
        />
        <!-- 距离数值 -->
        <text
          :x="(tree.nodes[edge.from].x + tree.nodes[edge.to].x) / 2 - 10"
          :y="(tree.nodes[edge.from].y + tree.nodes[edge.to].y) / 2"
          font-size="12"
          fill="#555"
          text-anchor="middle"
          dominant-baseline="middle"
        >
          {{ edge.l }}
        </text>
      </g>
      <!-- 绘制节点 -->
      <g
        v-for="(node, index) in visibleNodes"
        :key="index"
        @click="selectNode(node)"
      >
        <circle :cx="node.x" :cy="node.y" r="15" :fill="getNodeColor(node)" />
        <text :x="node.x - 5" :y="node.y + 5" font-size="12" fill="#fff">
          {{ node.label }}
        </text>
      </g>
      <text :x="resultText.x" :y="resultText.y" font-size="12" fill="red">
        {{ resultText.value }}
      </text>
    </svg>
  </div>
</template>

<script>
import { ref } from "vue";
import { useRouter } from "vue-router";

export default {
  name: "TopologyTree",
  setup() {
    const router = useRouter();
    const width = 900;
    const height = 600;

    // 定义拓扑树结构
    const tree = {
      nodes: [
        { id: 0, label: "A", x: 400, y: 50 },
        { id: 1, label: "B", x: 275, y: 150 },
        { id: 2, label: "C", x: 525, y: 150 },
        { id: 3, label: "D", x: 150, y: 250 },
        { id: 4, label: "E", x: 400, y: 250 },
        { id: 5, label: "F", x: 140, y: 450 },
        { id: 6, label: "D", x: 650, y: 250 },
        { id: 7, label: "C", x: 25, y: 350 },
        { id: 8, label: "E", x: 140, y: 350 },
        { id: 9, label: "F", x: 250, y: 350 },
        { id: 10, label: "D", x: 350, y: 350 },
        { id: 11, label: "F", x: 475, y: 350 },
        { id: 12, label: "F", x: 400, y: 450 },
        { id: 13, label: "B", x: 550, y: 350 },
        { id: 14, label: "E", x: 650, y: 350 },
        { id: 15, label: "F", x: 750, y: 350 },
        { id: 16, label: "E", x: 550, y: 450 },
        { id: 17, label: "F", x: 650, y: 450 },
        { id: 18, label: "F", x: 550, y: 550 },
        { id: 19, label: "C", x: 300, y: 450 },
      ],
      edges: [
        { from: 0, to: 1, l: 8 },
        { from: 0, to: 2, l: 20 },
        { from: 1, to: 3, l: 20 },
        { from: 1, to: 4, l: 40 },
        { from: 2, to: 6, l: 10 },
        { from: 3, to: 7, l: 10 },
        { from: 3, to: 8, l: 40 },
        { from: 3, to: 9, l: 10 },
        { from: 4, to: 10, l: 40 },
        { from: 4, to: 11, l: 25 },
        { from: 8, to: 5, l: 25 },
        { from: 10, to: 12, l: 25 },
        { from: 10, to: 19, l: 10 },
        { from: 6, to: 13, l: 20 },
        { from: 6, to: 14, l: 40 },
        { from: 6, to: 15, l: 10 },
        { from: 13, to: 16, l: 40 },
        { from: 14, to: 17, l: 25 },
        { from: 16, to: 18, l: 25 },
      ],
    };
    const resultText = ref({
      x: 0,
      y: 0,
      value: "",
    });

    // 初始化时仅显示 A, B, C 节点
    const visibleNodes = ref(tree.nodes);
    const visibleEdges = ref(tree.edges);

    // 当前选中的节点
    const selectedNode = ref(null);

    // 获取节点颜色（高亮当前选中的节点）
    const getNodeColor = (node) => {
      return node.label.includes("F") ? "#ff4d4f" : "#1890ff";
    };

    // 选择节点，并加载其子节点
    const selectNode = (node) => {
      selectedNode.value = node;

      // 加载选中节点的子节点和相关联的边
      const newNodes = tree.nodes.filter((n) =>
        tree.edges.some((e) => e.from === node.id && e.to === n.id)
      );
      newNodes.forEach((n) => {
        if (!visibleNodes.value.some((vn) => vn.id === n.id)) {
          visibleNodes.value.push(n);
        }
      });
      tree.edges
        .filter((e) => e.from === node.id)
        .forEach((e) => {
          if (
            !visibleEdges.value.some(
              (ve) => ve.from === e.from && ve.to === e.to
            )
          ) {
            visibleEdges.value.push(e);
          }
        });

      if (node.label == "F") {
        let nowNode = tree.edges.find((e) => e.to === node.id);
        let str = "";
        let str2 = "";
        let sum = 0;
        while (nowNode) {
          str = nowNode.l + (str !== "" ? "+" + str : "");
          sum += nowNode.l;
          nowNode = tree.edges.find((e) => e.to === nowNode.from);
        }
        str = str + "=" + sum;
        resultText.value.x = node.x - 40;
        resultText.value.y = node.y + 30;
        resultText.value.value = str;
      }
    };

    const goUrl = (name) => {
      router.push({ name: name });
    };
    return {
      width,
      height,
      tree,
      visibleNodes,
      visibleEdges,
      selectedNode,
      getNodeColor,
      selectNode,
      resultText,
      goUrl,
    };
  },
};
</script>

<style scoped>
.topology-tree {
  display: flex;
  flex-direction: column;
  align-items: center;
}
svg {
  border: 1px solid #ccc;
  margin-bottom: 20px;
}
button {
  padding: 10px 20px;
  background-color: #1890ff;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}
button:hover {
  background-color: #40a9ff;
}
</style>